package dao

import (
	"activity_srv/activity"
	"activity_srv/internal/utils"
	"activity_srv/model"
	"errors"
	"fmt"
	"smart-health-platforms/config"

	"time"
)

// 创建拼团
func CreateGroup(in *activity.CreateGroupRequest) (*model.GrouponRecord, error) {
	// 记录请求开始日志
	fmt.Printf("开始创建拼团: UserId=%d, ProductId=%d, ProductNum=%d\n", in.UserId, in.ProductId, in.ProductNum)

	// 参数验证
	if in.UserId <= 0 {
		fmt.Printf("参数验证失败: 用户ID不能为空\n")
		return nil, errors.New("用户ID不能为空")
	}
	if in.ProductId <= 0 {
		fmt.Printf("参数验证失败: 拼团商品ID不能为空\n")
		return nil, errors.New("拼团商品ID不能为空")
	}
	if in.ProductNum <= 0 {
		fmt.Printf("参数验证失败: 购买数量必须大于0\n")
		return nil, errors.New("购买数量必须大于0")
	}

	var groupProduct model.GrouponProduct
	// 根据商品ID查询拼团商品信息
	fmt.Printf("查询拼团商品信息: ProductId=%d\n", in.ProductId)
	if err := groupProduct.GetGrouponProductById(int(in.ProductId)); err != nil {
		fmt.Printf("查询拼团商品信息失败: %v\n", err)
		return nil, fmt.Errorf("查询拼团商品信息失败: %v", err)
	}
	// 打印查询到的商品信息
	fmt.Printf("查询到的商品信息: Id=%d, ProductName=%s, ProductStock=%d, MemberNum=%d, GroupPrice=%f, Status=%d\n",
		groupProduct.Id, groupProduct.ProductName, groupProduct.ProductStock, groupProduct.MemberNum, groupProduct.GroupPrice, groupProduct.Status)

	// 检查拼团商品是否存在且有效
	if groupProduct.Id == 0 {
		fmt.Printf("拼团商品不存在: ProductId=%d\n", in.ProductId)
		return nil, errors.New("拼团商品不存在")
	}
	if groupProduct.Status != 1 {
		fmt.Printf("拼团商品未开始: ProductId=%d, Status=%d\n", in.ProductId, groupProduct.Status)
		return nil, errors.New("拼团商品未开始")
	}

	// 检查拼团商品库存是否充足
	if groupProduct.ProductStock < uint(in.ProductNum) {
		fmt.Printf("拼团商品库存不足: 当前库存=%d, 需求数量=%d\n", groupProduct.ProductStock, in.ProductNum)
		return nil, fmt.Errorf("该拼团商品库存不足(当前库存:%d)", groupProduct.ProductStock)
	}

	now := time.Now()
	var expireTime time.Time
	var people uint64
	var price float64
	var groupType uint8 = 0 // 默认是普通拼团

	// 根据拼团类型设置不同的参数
	if in.GroupType > 0 {
		groupType = 1                               // 超级拼团
		expireTime = now.Add(48 * time.Hour)        // 超级拼团有效期48小时
		people = uint64(groupProduct.MemberNum * 2) // 超级拼团人数是普通拼团的2倍
		price = groupProduct.GroupPrice * 0.6       // 超级拼团价格是普通拼团的6折
	} else {
		expireTime = now.Add(24 * time.Hour)    // 普通拼团有效期24小时
		people = uint64(groupProduct.MemberNum) // 普通拼团人数
		price = groupProduct.GroupPrice         // 普通拼团价格
	}

	// 生成邀请码
	inviteCode := utils.GenerateInviteCode()

	// 使用年月日时间格式生成GroupSn，格式为：YYYYMMDD+用户ID+随机数
	timeStr := now.Format("20060102")
	randomNum := utils.GenerateRandomNumber(6) // 生成6位随机数
	groupSn := fmt.Sprintf("%s%s%d", timeStr, fmt.Sprint(in.UserId), randomNum)

	group := model.GrouponRecord{
		UserId:       uint(in.UserId),
		ProductId:    uint(in.ProductId),
		GroupSn:      groupSn,
		ProductNum:   uint(in.ProductNum),
		ProductPrice: price,
		UserOrderSn:  in.UserOrderSn,
		GroupPrice:   price * float64(in.ProductNum),
		GroupNum:     uint(people),
		Status:       0, //表示拼团进行中
		GroupAdd:     now,
		GroupEnd:     expireTime,
		UserType:     1, //1代表拼团团长
		InviteCode:   inviteCode,
		GroupType:    uint(groupType),
	}
	if err := group.CreateGroup(); err != nil {
		return nil, fmt.Errorf("创建拼团失败: %v", err)
	}

	// 保存拼团邀请码记录
	inviteCodeRecord := &model.GrouponInviteCode{
		InviteCode: inviteCode,
		GroupId:    group.Id,
		UserId:     group.UserId,
		ExpiredAt:  group.GroupEnd,
	}

	err := config.DB.Create(inviteCodeRecord).Error
	if err != nil {
		// 记录错误但不中断主流程
		fmt.Printf("保存邀请码记录失败: %v\n", err)
	}

	return &group, nil
}

// JoinGroup 团员参与拼团
func JoinGroup(inviteCode string, userId, productNum int64, userOrderSn string) (*model.GrouponRecord, error) {
	// 记录请求开始日志
	fmt.Printf("开始参与拼团: UserId=%d, InviteCode=%s, ProductNum=%d\n", userId, inviteCode, productNum)

	// 参数验证
	if userId <= 0 {
		fmt.Printf("参数验证失败: 用户ID不能为空\n")
		return nil, errors.New("用户ID不能为空")
	}
	if inviteCode == "" {
		fmt.Printf("参数验证失败: 邀请码不能为空\n")
		return nil, errors.New("邀请码不能为空")
	}
	// 验证邀请码格式是否为6位数字
	if len(inviteCode) != 6 {
		fmt.Printf("参数验证失败: 邀请码格式不正确，应为6位数字\n")
		return nil, errors.New("邀请码格式不正确，请使用6位数字的邀请码")
	}
	if productNum <= 0 {
		fmt.Printf("参数验证失败: 购买数量必须大于0\n")
		return nil, errors.New("购买数量必须大于0")
	}

	// 1. 验证邀请码是否有效
	var inviteCodeRecord model.GrouponInviteCode
	fmt.Printf("验证邀请码: %s\n", inviteCode)
	err := config.DB.Where("invite_code = ? AND expired_at > NOW()", inviteCode).First(&inviteCodeRecord).Error
	if err != nil {
		fmt.Printf("邀请码无效或已过期: %s, 错误: %v\n", inviteCode, err)
		return nil, errors.New("邀请码无效或已过期")
	}
	fmt.Printf("邀请码验证通过: GroupId=%d, UserId=%d\n", inviteCodeRecord.GroupId, inviteCodeRecord.UserId)

	// 2. 获取拼团信息
	var groupRecord model.GrouponRecord
	fmt.Printf("获取拼团信息: GroupId=%d\n", inviteCodeRecord.GroupId)
	err = config.DB.Where("id = ?", inviteCodeRecord.GroupId).First(&groupRecord).Error
	if err != nil {
		fmt.Printf("拼团不存在: GroupId=%d, 错误: %v\n", inviteCodeRecord.GroupId, err)
		return nil, errors.New("拼团不存在")
	}

	// 检查拼团状态和结束时间
	if groupRecord.Status != 0 {
		fmt.Printf("拼团状态异常: GroupId=%d, Status=%d\n", groupRecord.Id, groupRecord.Status)
		return nil, errors.New("拼团状态异常")
	}

	// 检查拼团是否已结束
	now := time.Now()
	if now.After(groupRecord.GroupEnd) {
		fmt.Printf("拼团已结束: GroupId=%d, GroupEnd=%v\n", groupRecord.Id, groupRecord.GroupEnd)

		// 检查当前拼团人数
		var memberCount int64
		config.DB.Model(&model.GrouponRecord{}).Where("group_sn = ?", groupRecord.GroupSn).Count(&memberCount)
		fmt.Printf("当前拼团人数: %d, 总人数限制: %d\n", memberCount, groupRecord.GroupNum)

		// 如果人数未达要求，更新状态为拼团失败
		if memberCount < int64(groupRecord.GroupNum) {
			fmt.Printf("拼团结束但人数未达要求，更新状态为失败: GroupSn=%s\n", groupRecord.GroupSn)
			config.DB.Model(&model.GrouponRecord{}).Where("group_sn = ?", groupRecord.GroupSn).Update("status", 2)
		}

		return nil, errors.New("拼团已结束")
	}
	fmt.Printf("拼团信息: GroupId=%d, GroupSn=%s, Status=%d, GroupNum=%d\n",
		groupRecord.Id, groupRecord.GroupSn, groupRecord.Status, groupRecord.GroupNum)

	// 3. 检查当前拼团人数是否已满
	var memberCount int64
	config.DB.Model(&model.GrouponRecord{}).Where("group_sn = ?", groupRecord.GroupSn).Count(&memberCount)
	fmt.Printf("当前拼团人数: %d, 总人数限制: %d\n", memberCount, groupRecord.GroupNum)
	if memberCount >= int64(groupRecord.GroupNum) {
		fmt.Printf("拼团人数已满: GroupSn=%s, 当前人数=%d, 总人数=%d\n", groupRecord.GroupSn, memberCount, groupRecord.GroupNum)
		return nil, errors.New("拼团人数已满")
	}

	// 4. 检查用户是否已参与该拼团
	var existingMemberCount int64
	config.DB.Model(&model.GrouponRecord{}).Where("group_sn = ? AND user_id = ?", groupRecord.GroupSn, userId).Count(&existingMemberCount)
	if existingMemberCount > 0 {
		fmt.Printf("用户已参与该拼团: UserId=%d, GroupSn=%s\n", userId, groupRecord.GroupSn)
		return nil, errors.New("您已参与该拼团")
	}

	// 5. 创建团员拼团记录
	now = time.Now()
	memberGroup := model.GrouponRecord{
		UserId:       uint(userId),
		ProductId:    groupRecord.ProductId,
		GroupSn:      groupRecord.GroupSn,
		ProductNum:   uint(productNum),
		ProductPrice: groupRecord.ProductPrice,
		UserOrderSn:  userOrderSn,
		GroupPrice:   groupRecord.ProductPrice * float64(productNum),
		GroupNum:     groupRecord.GroupNum,
		Status:       0, // 表示拼团进行中
		GroupAdd:     now,
		GroupEnd:     groupRecord.GroupEnd,
		UserType:     2, // 2代表拼团团员
		InviteCode:   inviteCode,
		GroupType:    groupRecord.GroupType,
	}

	if err := memberGroup.CreateGroup(); err != nil {
		fmt.Printf("参与拼团失败: %v\n", err)
		return nil, fmt.Errorf("参与拼团失败: %v", err)
	}
	fmt.Printf("团员拼团记录创建成功: GroupId=%d, UserId=%d\n", memberGroup.Id, memberGroup.UserId)

	// 6. 检查是否达到成团人数，如果达到则更新所有拼团记录状态为拼团成功
	var updatedMemberCount int64
	config.DB.Model(&model.GrouponRecord{}).Where("group_sn = ?", groupRecord.GroupSn).Count(&updatedMemberCount)
	fmt.Printf("更新后拼团人数: %d, 总人数限制: %d\n", updatedMemberCount, groupRecord.GroupNum)

	if updatedMemberCount == int64(groupRecord.GroupNum) {
		// 更新所有团员的拼团状态为成功
		fmt.Printf("拼团人数已达上限，更新状态为成功: GroupSn=%s\n", groupRecord.GroupSn)
		config.DB.Model(&model.GrouponRecord{}).Where("group_sn = ?", groupRecord.GroupSn).Update("status", 1)
	}

	return &memberGroup, nil
}
